package com.cyjt.operation.bluetooth;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.cyjt.operation.base.HandlerMessageCodes;
import com.cyjt.operation.uitools.CHexConver;
import com.cyjt.operation.uitools.CharacterTool2;

/**
 * Created by mac on 15/3/18.
 */
public class BlueToothService {
	private static final String NAME_SECURE = "BluetoothSecure";
	private static final String NAME_INSECURE = "BluetoothInsecure";
	/**
	 * 串口通信服务标准UUID
	 */
	private static final UUID MY_UUID_SECURE = UUID
			.fromString("00001101-0000-1000-8000-00805F9B34FB");
	private static final UUID MY_UUID_INSECURE = UUID
			.fromString("00001101-0000-1000-8000-00805F9B34FB");
	/**
	 * 蓝牙
	 */
	private final BluetoothAdapter mAdapter;
	/**
	 * 事务消息处理
	 */
	private final Handler mHandler;
	// 当前连接状态
	private int mState;
	/**
	 * 什么都没做
	 */
	public static final int STATE_NONE = 0;
	/**
	 * 正在监听连接请求
	 */
	public static final int STATE_LISTEN = 1;
	/**
	 * 正在建立通信信道
	 */
	public static final int STATE_CONNECTING = 2;
	/**
	 * 已经完成连接建立，可以发送及接收数据
	 */
	public static final int STATE_CONNECTED = 3;
	private ConnectThread mConnectThread;
	private ConnectedThread mConnectedThread;

	/**
	 * 构造函数，准备一个新的蓝牙通信信道
	 * 
	 * @param context
	 *            UI Activity
	 * @param handler
	 *            处理返回到UI Activity信息的Handler
	 */
	public BlueToothService(Context context, Handler handler) {
		mAdapter = BluetoothAdapter.getDefaultAdapter();
		mHandler = handler;
		stop();
	}

	/**
	 * 设置当前的连接状态
	 * 
	 * @param state
	 *            提供的State参数
	 */
	private synchronized void setState(int state) {
		mState = state;
		// 将当前状态发送给UI Activity
		mHandler.obtainMessage(
				HandlerMessageCodes.BLUETOOTH_MESSAGE_STATE_CHANGE, state, -1)
				.sendToTarget();
	}

	public int getState() {

		return mState;
	}

	/**
	 * 开启ConnectThread线程来初始连接到远程设备
	 * 
	 * @param device
	 *            要连接的目标device
	 * @param secure
	 *            Socket Security type - Secure (true) , Insecure (false)
	 */
	public synchronized void connect(BluetoothDevice device, boolean secure) {

		// 如果连接线程在运行则取消之
		if (mState == STATE_CONNECTING) {
			if (mConnectThread != null) {
				mConnectThread.cancel();
				mConnectThread = null;
			}
		}

		// 如果数据传输线程在运行则取消
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		// 开启连接目标device的线程
		mConnectThread = new ConnectThread(device, secure);
		mConnectThread.start();
		// 设置mState的值，作为重启connect时用到的标志
		setState(STATE_CONNECTING);

	}

	/**
	 * Start the ConnectedThread to begin managing a Bluetooth connection
	 * 
	 * @param socket
	 *            The BluetoothSocket on which the connection was made
	 * @param device
	 *            已经完成连接的蓝牙设备
	 */
	public synchronized void connected(BluetoothSocket socket,
			BluetoothDevice device) {
		// 完成连接后先取消所有的线程=====================================
		// 取消连接线程ConnectThread
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		// 取消数据通信线程
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}
		// 开启数据传输
		mConnectedThread = new ConnectedThread(socket);
		mConnectedThread.start();
		// // 将连接上的设备名以及地址发送给UI Activity
		// Message msg =
		// mHandler.obtainMessage(HandlerCode.BLUETOOTH_MESSAGE_DEVICE_CONNECTED);
		// Bundle bundle = new Bundle();
		// bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());
		// bundle.putString(BluetoothChat.DEVICE_ADDRESS, device.getAddress());
		// msg.setData(bundle);
		// mHandler.sendMessage(msg);
		// 将已连接状态发送给UI Activity
		setState(STATE_CONNECTED);
	}

	/**
	 * 停止所有线程
	 */
	public synchronized void stop() {
		// 停止建立连接
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}
		// 停止数据传输
		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}
		setState(STATE_NONE);
	}

	/**
	 * 使用非同步的方式写数据
	 * 
	 * @param message
	 *            要写出的数据
	 */
	public void sendMessage(String message) {
		// 创建一个临时对象
		ConnectedThread r;
		// 同步同一个ConnectedThread对象
		synchronized (this) {
			if (mState != STATE_CONNECTED) {
				mHandler.obtainMessage(
						HandlerMessageCodes.BLUETOOTH_MESSAGE_TOAST_NO_CONNECTED)
						.sendToTarget();
				return;
			}
			r = mConnectedThread;
		}
		// 执行写不同步
		r.write(message);
	}

	/**
	 * 连接失败
	 */
	private void connectionFailed() {

		mHandler.obtainMessage(
				HandlerMessageCodes.BLUETOOTH_MESSAGE_TOAST_FAILED_CONNECTION)
				.sendToTarget();
		//
		// // Start the service over to restart listening mode
		// // 再次开启连接监听
		// BluetoothChatService.this.start();
	}

	/**
	 * 如果连接断开，通知UI
	 */
	private void connectionLost() {
		// 返回故障信息给Activity
		mHandler.obtainMessage(
				HandlerMessageCodes.BLUETOOTH_MESSAGE_TOAST_LOST_CONNECTION)
				.sendToTarget();
		//
		// // 再次开启连接监听
		// BluetoothChatService.this.start();
	}

	/**
	 * 这个线程将对目标发起主动连接
	 */
	private class ConnectThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final BluetoothDevice mmDevice;
		private String mSocketType;

		/**
		 * 这是其构造函数
		 * 
		 * @param device
		 *            要连接的远端蓝牙设备
		 * @param secure
		 *            连接方式（安全或不安全）
		 */
		public ConnectThread(BluetoothDevice device, boolean secure) {
			mmDevice = device;
			BluetoothSocket tmp = null;
			mSocketType = secure ? "Secure" : "Insecure";
			// 通过传入的远端BluetoothDevice获得用来连接的BluetoothSocket
			try {
				if (secure) {
					tmp = device
							.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
				} else {
					tmp = device
							.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
				}
			} catch (IOException e) {
			}
			mmSocket = tmp;
		}

		public void run() {
			setName("ConnectThread" + mSocketType);
			// 取消 discovery线程
			mAdapter.cancelDiscovery();
			// 创建BluetoothSocket连接
			try {
				// mmSocket.connect()方法将会阻塞线程，直到成功连接或抛出异常
				mmSocket.connect();
			} catch (IOException e) {
				// 抛出异常的时候应该关掉通信连接
				try {
					mmSocket.close();
				} catch (IOException e2) {

				}
				connectionFailed();
				return;
			}
			// 完成连接后重置连接线程，监听下次的连接
			synchronized (BlueToothService.this) {
				mConnectThread = null;
			}
			// 已连接，开启数据传输线程
			connected(mmSocket, mmDevice);
		}

		public void cancel() {
			try {
				mmSocket.close();
			} catch (IOException e) {

			}
		}
	}

	/**
	 * 这个线程将一直运行在与远程设备保持连接的过程中 它将处理输入输出数据
	 */
	private class ConnectedThread extends Thread {
		private final BluetoothSocket mmSocket;
		private final InputStream mmInStream;
		private final OutputStream mmOutStream;

		public ConnectedThread(BluetoothSocket socket) {
			mmSocket = socket;
			InputStream tmpIn = null;
			OutputStream tmpOut = null;
			// 获得蓝牙通信需要的输入输出流
			try {
				tmpIn = socket.getInputStream();
				tmpOut = socket.getOutputStream();
			} catch (IOException e) {

			}
			mmInStream = tmpIn;
			mmOutStream = tmpOut;
		}

		public void run() {
			byte[] buffer = new byte[1024];
			byte[] bu_temp = new byte[1024];
			int bytes;
			int bytes_temp = 0;
			// 在连接了之后保持对输入的监听
			// 这里使用死循环一直等待并接收数据
			try {
				while ((bytes = mmInStream.read(buffer, 0, 1024)) > -1) {

					// 得到输入的数据
					// bytes = mmInStream.read(buffer);
					Log.v("demo", "数据尺寸：" + bytes);
					// 将接收到的数据返回给 UI Activity
					bytes_temp += bytes;
					for (int i = bytes_temp - bytes; i < bytes_temp; i++) {
						bu_temp[i] = buffer[i - (bytes_temp - bytes)];
					}
					// if (bytes_temp == 12) {
					// if (CHexConver.byte2HexStr(bu_temp,
					// bytes_temp).startsWith("AA220000"))
					// mHandler.obtainMessage(HandlerCode.BLUETOOTH_MESSAGE_READED_STREAM,
					// CHexConver.byte2HexStr(bu_temp,
					// bytes_temp)).sendToTarget();
					// bytes_temp = 0;
					// }
					String s = CHexConver.byte2HexStr(bu_temp, bytes_temp)
							.replace(" ", "");
					Log.v("demo", "数据累计:" + s);
					if (s.length() > 12 && (s.split("AA220000", 2).length > 1)) {
						s = s.split("AA220000", 2)[1];
						if (s.length() >= 16) {
							s = s.substring(0, 16);
							Log.v("demo", "数据解析:" + s);
							mHandler.obtainMessage(
									HandlerMessageCodes.BLUETOOTH_MESSAGE_READED_STREAM,
									"AA220000" + s).sendToTarget();
							bytes_temp = 0;
						}
					}
				}
			} catch (IOException e) {
				connectionLost();
				// // 出问题后从连接监听重新开始
				// BluetoothChatService.this.start();
			}

		}

		/**
		 * 朝连接上的设备发送数据
		 * 
		 * @param message
		 *            要发送的数据
		 */
		public void write(String message) {
			try {
				byte[] buffer = CharacterTool2.HexString2Bytes(message);
				mmOutStream.write(buffer);
				// 将已经发送完成的数据返回给 UI Activity
				mHandler.obtainMessage(
						HandlerMessageCodes.BLUETOOTH_MESSAGE_WRITED_STREAM,
						CHexConver.byte2HexStr(buffer, buffer.length))
						.sendToTarget();
			} catch (IOException e) {

			}
		}

		public void cancel() {
			try {
				mmInStream.close();
				mmOutStream.close();
				mmSocket.close();
			} catch (IOException e) {

			}
		}
	}

}
